/*	Keeps track of the state of a behavior.  Instead of having each behavior implement their own internal
	functionality to monitor its internal state, we are abstracting in much the same way a Finite State Machine
	abstracts state management from individual states.
	
	Original credit for a java implementation to: http://magicscrollsofcode.blogspot.com/2010/12/behavior-trees-by-example-ai-in-android.html
*/

#ifndef BEHAVIORCONTROLLER_H_
#define BEHAVIORCONTROLLER_H_

#include "BaseBehavior.h"
#include <vector>

class BaseBehavior;

class BehaviorController
{
public:
	
	/**
	 * Creates a new instance of the BehaviorController class
	 * @param behavior Behavior to controll.
	 */
	BehaviorController(BaseBehavior* incBehavior) : done(false), success(true), started(false), behavior(incBehavior)	{}
	
	/**
	 * Indicates whether the behavior finished successfully
	 * @return True if it did, false if it didn't
	 */
	bool Failed()		{	/*DEBUG_PRINT("Behavior Controller(%p) with behavior(%p) checking failed: %d.\n", this, behavior, success);*/ return !success;	}
	
	/**
	 * Indicates whether the behavior finished
	 * @return True if it did, false if it didn't
	 */
	bool Finished()		{	/*DEBUG_PRINT("Behavior Controller(%p) with behavior(%p) checking finished: %d.\n", this, behavior, done);*/ return done;		}
	
	/**
	 * Indicates whether the behavior has started or not
	 * @return True if it has, false if it hasn't
	 */
	bool Started()		{	/*DEBUG_PRINT("Behavior Controller(%p) with behavior(%p) checking started: %d.\n", this, behavior, started);*/ return started;		}
	
	/**
	 * Indicates whether the behavior finished successfully
	 * @return True if it did, false if it didn't
	 */
	bool Succeeded()	{	/*DEBUG_PRINT("Behavior Controller(%p) with behavior(%p) checking succeeded: %d.\n", this, behavior, success);*/ return success;		}
	
	/**
	 * Marks the behavior as just started.
	 */
	void Reset()		{	DEBUG_PRINT("Behavior Controller(%p) with behavior(%p) reset.\n", this, behavior); done = false; success = true; started = false;	}
	
	/**
	 * Sets the task reference
	 * @param behavior Behavior to monitor
	 */
	void SetBehavior(BaseBehavior* incBehavior)		{	behavior = incBehavior;		}
	
	/**
	 * Starts the monitored class
	 */
	void SafeEnter();
	
	/**
	 * Ends the monitored behavior
	 */
	void SafeExit();

	/**
	 * Ends the monitored class, with success
	 */
	virtual void FinishWithSuccess();

	/**
	 * Ends the monitored class, with failure
	 */
	virtual void FinishWithFailure();

	/**
	 * Here for debugging purposes, mainly for debug printing of tree
	 */
	virtual std::vector<BaseBehavior*>* GetSubBehaviors()	{	return NULL;	}
	
private:
	/**
	 * Indicates whether the task is finished or not
	 */
	bool done;
	
	/**
	 * If finished, it indicates if it has finished with success or not
	 */
	bool success;
	
	/**
	 * Indicates if the task has started or not
	 */
	bool started;
	
	/**
	 * Reference to the behahvior we monitor
	 */
	BaseBehavior* behavior;

};

#endif
